﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using MvcTasks.Models;
using System.IO;
using System.Xml.Serialization;
using System.Text;
using MvcTasks.ModelView.Tasks;
using System.Xml.Linq;
using Common.Constants;
using Common;

namespace MvcTasks.Controllers
{
    public class TasksController : Controller
    {
        private IDbContextWrapper db;
        private ITasksModelView tasksModelView;
        

        public TasksController()
        {
            db = new DbContextWrapper();
            tasksModelView = new TasksModelView();
           
        }

        public TasksController(IDbContextWrapper context)
        {
            db = context;
        }

        // GET: Tasks
        public ActionResult Index()
        {
            using (db.Open())
            {
                return View(tasksModelView);
            }
        }

        public ActionResult Upload()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Import()
        {

            foreach (string file in Request.Files)
            {
                var hpf = Request.Files[file];
                if (hpf.ContentLength == 0)
                    continue;



                List<RandomTask> tasks = new List<RandomTask>();
                // Construct an instance of the XmlSerializer with the type
                // of object that is being deserialized.
                XmlSerializer mySerializer =
                new XmlSerializer(typeof(List<RandomTask>));

                string savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(hpf.FileName));
                hpf.SaveAs(savedFileName);

                var reader = new StreamReader(savedFileName, Encoding.UTF8);

                XDocument doc = XDocument.Load(reader);

                var query = (from outerTask in doc.Elements()
                            from task in outerTask.Elements(XmlConstants.RandomTask.ToString()).Union(outerTask.Elements(XmlConstants.Tasks.ToString()))
                            let id = task.Element(XmlConstants.ID.ToString())
                            let title = task.Element(XmlConstants.Title.ToString())
                            let genre = task.Element(XmlConstants.Genre.ToString())
                            let description = task.Element(XmlConstants.Description.ToString())
                            let priority = task.Element(XmlConstants.Priority.ToString())

                            let url = task.Element(XmlConstants.Url.ToString())
                            select new RandomTask
                            {
                               ID  = Convert.ToInt32(id.Value),
                               Title = title == null?null:title.Value,
                               Genre = genre== null?null:genre.Value,
                               Description = description == null?null:description.Value,
                               Priority = Convert.ToInt32(priority.Value),
                               PercentageDone = 0
                            }).ToList();

                using (db.Open())
                {
                    var list = db.RandomTask.ToList();
                    db.RandomTask.RemoveRange(list);
                    db.SaveChanges();

                    db.RandomTask.AddRange(query);
                    db.SaveChanges();

                }
            }
            return RedirectToAction("Index");

        }

        public void Export()
        {

            IEnumerable<RandomTask> list ;
            using (db.Open())
            {
                list = db.RandomTask.ToList();
            }
    
            Response.ClearContent();

            Response.AddHeader("content-disposition", "attachment;filename=Exported_Users.xml");

            Response.ContentType = "text/xml";

            
            // Insert code to set properties and fields of the object.
            XmlSerializer mySerializer = new
            XmlSerializer(typeof(List<RandomTask>));
            // To write to a file, create a StreamWriter object.
            StringWriter myWriter = new StringWriter();
            mySerializer.Serialize(myWriter, list);
  

            Response.Write(myWriter);


            myWriter.Close();

            Response.End();
        }

        public ActionResult GetMe()
        {
            using (db.Open())
            {
                var list = db.RandomTask.ToList();
                var maxPriority = list.Max(x => x.Priority);
                
                var total = new List<int>();
                list.ForEach(y =>
                    {
                        total.AddRange(Enumerable.Repeat(y.ID, maxPriority / y.Priority));
                    });
                

                Random rmd = new Random((int)DateTime.Now.Ticks);
                var index = rmd.Next(total.Count);
                return View(list.FirstOrDefault(x => x.ID == total[index]));
            }
            

        }

        public ActionResult ItemDetails(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            RandomTask tasks;
            using (db.Open())
            {
                tasks = db.RandomTask.Find(id);
                
            }
            if (tasks == null)
            {
                return HttpNotFound();
            }
            return View(tasks);
        }

        // GET: Tasks/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            RandomTask tasks;
            using (db.Open())
            {
                tasks = db.RandomTask.Find(id);
            }
            if (tasks == null)
            {
                return HttpNotFound();
            }
            return View(tasks);
        }

        // GET: Tasks/Create
         [Authorize(Users = "brettwill@datazug.ch")]
        public ActionResult Create()
        {
            return View();
        }

        // POST: Tasks/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        [Authorize(Users = "brettwill@datazug.ch")]
        public ActionResult Create([Bind(Include = "ID,Title,Genre,Priority, Description, Url")] RandomTask tasks)
        {
            if (ModelState.IsValid)
            {
                using (db.Open())
                {
                    db.RandomTask.Add(tasks);
                    db.SaveChanges();
                }
                return RedirectToAction("Index");
            }

            return View(tasks);
        }

        // GET: Tasks/Edit/5
        
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            using (db.Open())
            {
                RandomTask tasks = tasksModelView.Find(id);
                if (tasks == null)
                {
                    return HttpNotFound();
                }
                return View(tasksModelView);
            }
        }

        // POST: Tasks/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(TasksModelView taskModelView)
        {
            if (ModelState.IsValid)
            {
                
                using (db.Open())
                {

                    db.Entry(taskModelView.CurrentItem).State = EntityState.Modified;
                    db.SaveChanges();
                }
                return RedirectToAction("Index");
            }
            return View(taskModelView);
        }

        // GET: Tasks/Delete/5
        [Authorize(Users = "brettwill@datazug.ch")]
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            using (db.Open())
            {
                RandomTask tasks = db.RandomTask.Find(id);
                if (tasks == null)
                {
                    return HttpNotFound();
                }
                return View(tasks);
            }
        }

        // POST: Tasks/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            using (db.Open())
            {
                RandomTask tasks = db.RandomTask.Find(id);
                db.RandomTask.Remove(tasks);
                db.SaveChanges();
            }
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}
